package xyz.scootaloo.kami.server.controller.handler

import io.vertx.core.Handler
import io.vertx.ext.auth.User
import io.vertx.ext.web.Router
import io.vertx.ext.web.RoutingContext
import io.vertx.kotlin.coroutines.await
import xyz.scootaloo.kami.server.controller.coroutineReqHandle
import xyz.scootaloo.kami.server.standard.getLogger
import xyz.scootaloo.kami.server.service.Constant.HTTP_AUTHORIZATION
import xyz.scootaloo.kami.server.service.JwtService

/**
 * @author flutterdash@qq.com
 * @since 2022/2/6 21:11
 */

fun attachJwtHandler(mountPoint: String, router: Router) {
    router.route("${mountPoint}*").handler(JwtHandler)
}

private object JwtHandler : Handler<RoutingContext> {
    private val log by lazy { getLogger() }
    private val jwtService = JwtService()

    override fun handle(ctx: RoutingContext) {
        ctx.coroutineReqHandle(log) {
            val jwt = ctx.request().getHeader(HTTP_AUTHORIZATION)
            if (jwt == null) {
                handleNotLoggedUser(ctx)
            } else {
                handleLoggedUser(ctx, jwt)
            }
        }
    }

    private fun handleNotLoggedUser(ctx: RoutingContext) {
        ctx.setUser(User.create(jwtService.guestUserPrincipal()))
        ctx.next()
    }

    private suspend fun handleLoggedUser(ctx: RoutingContext, jwt: String) {
        val user = jwtService.authenticate(jwt).await()
        ctx.setUser(user)
        ctx.next()
    }
}